package utils

import (
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"os"
	"reflect"
)

// @title struct转map
func StructToMap(obj interface{}) map[string]interface{} {
	t := reflect.TypeOf(obj)
	v := reflect.ValueOf(obj)

	var data = make(map[string]interface{})
	for i := 0; i < t.NumField(); i++ {
		data[t.Field(i).Name] = v.Field(i).Interface()
	}
	return data
}

func StructsToMaps(objs interface{}) []map[string]interface{} {
	var data []map[string]interface{}
	t := reflect.TypeOf(objs)
	v := reflect.ValueOf(objs)

	if t.Kind() == reflect.Slice {
		for i := 0; i < v.Len(); i++ {
			data = append(data, StructToMap(v.Index(i).Interface()))
		}
	}
	return data
}

func StructToMapJson(obj interface{}) map[string]interface{} {
	t := reflect.TypeOf(obj)
	v := reflect.ValueOf(obj)

	var data = make(map[string]interface{})
	for i := 0; i < t.NumField(); i++ {
		jsonKey := t.Field(i).Tag.Get("json")
		if jsonKey != "-" {
			data[jsonKey] = v.Field(i).Interface()
		}
	}
	return data
}

func StructsToMapsJson(objs interface{}) []map[string]interface{} {
	var data []map[string]interface{}
	t := reflect.TypeOf(objs)
	v := reflect.ValueOf(objs)

	if t.Kind() == reflect.Slice {
		for i := 0; i < v.Len(); i++ {
			data = append(data, StructToMapJson(v.Index(i).Interface()))
		}
	}
	return data
}

// @title 判断目录是否存在
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}

	return false, err
}

// @title md5加密
func Md5(str string) string {
	h := md5.New()
	h.Write([]byte(str))
	return hex.EncodeToString(h.Sum(nil))
}

// @title 文件大小格式化
func FormatFileSize(size int) string {
	var str string
	if size < 1024 {
		str = "1KB"
	} else if size < 1024*1024 {
		str = fmt.Sprintf("%.2fKB", float64(size)/1024)
	} else if size < 1024*1024*1024 {
		str = fmt.Sprintf("%.2fMB", float64(size)/1024/1024)
	} else {
		str = fmt.Sprintf("%.2fGB", float64(size)/1024/1024/1024)
	}
	return str
}
